package services

import base.Message
import base.State
import beans.*
import common.permission.Permission
import common.permission.PermissionManager
import controllers.AdminController
import models.*
import utils.SafeUtil

class AdminService(controller: AdminController): BaseService<AdminController>(controller) {
    fun superUserLogin(username: String, passwd: String){
        val model = SuperUserM.findUserByUsername(username)
        if (model == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_USER_USER_NOT_EXIST))
            controller.renderJson(message)
            return
        }
        val localPasswd: String = model.get(SuperUserM.PASSWORD)
        if (localPasswd != passwd){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_USER_WRONG_PASSWORD))
            controller.renderJson(message)
            return
        }
        val token = SafeUtil.generateToken(model[UserM.ID], 60*60*24*15, model[UserM.PASSWORD])
        val user = SuperUser.fromModel(model)
        val message = Message(State.STATE_SUCCESS,
                data = hashMapOf("token" to token, "user" to user))

        controller.renderJson(message)
    }


    fun findReviewingList(){
        val records = RecordM.findReviewRecords()
        val reviews = record2Review(records)
        val message = Message(State.STATE_SUCCESS, data = reviews)
        controller.renderJson(message)
    }

    private fun record2Review(records: List<Record>): List<Record2Manage> {
        return records.map { record ->
            val user = UserM.AGENT.findById(record.userId)
            Record2Manage(record, extra = hashMapOf(
                    "username" to user[UserM.USERNAME],
                    "classes" to ClassificationM.getNameById(record.classes)
            ))
        }
    }

    fun changeRecordState(id: Int, state: Int){
        if (state != RecordState.PASS && state != RecordState.UNPASS && state !=RecordState.REVIEW){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_ILLEGAL_PARA))
            controller.renderJson(message)
            return
        }
        val recordM = RecordM.AGENT.findById(id)
        if (recordM == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_RECORD_NOT_RECORD))
            controller.renderJson(message)
        } else {
            recordM[RecordM.STATE] = state
            if (recordM.update()){
                val message = Message(State.STATE_SUCCESS, data = "")
                controller.renderJson(message)
            } else {
                val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_SERVER_INSIDE_ERROR))
                controller.renderJson(message)
            }
        }
    }

    fun queryRecord(content: String, type: String){
        val reviews = when(type){
            "id" -> queryRecordById(content)
            "title" -> queryRecordByTitle(content)
            "username" -> queryRecordByUsername(content)
            else -> listOf()
        }
        if (controller.render == null){
            val message = Message(State.STATE_SUCCESS, data = reviews)
            controller.renderJson(message)
        }
    }

    private fun queryRecordById(content: String): List<Record2Manage>{
        val id = content.toIntOrNull()
        if (id == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_ILLEGAL_PARA))
            controller.renderJson(message)
            return listOf()
        }
        val recordM = RecordM.AGENT.findById(id)
        if (recordM != null){
            val record = Record.from(recordM)
            return record2Review(listOf(record))
        }
        return listOf()
    }

    private fun queryRecordByTitle(title: String): List<Record2Manage>{
        return listOf()
    }

    private fun queryRecordByUsername(username: String): List<Record2Manage>{
        val user = UserM.findUserByUsername(username)
        if (user.isEmpty()){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_USER_USER_NOT_EXIST))
            controller.renderJson(message)
            return listOf()
        }
        val reviews = mutableListOf<Record2Manage>()
        user.forEach {
            val userId = it.getInt(UserM.ID)
            val records = RecordM.findRecordByUserId(userId)
            if (records.isNotEmpty()){
                reviews.addAll(record2Review(records))
            }
        }
        return reviews
    }

    fun queryUser(content: String, type: String){
        val users = when(type){
            "id" -> queryUserById(content)
            "username" -> queryUserByUsername(content)
            "phone" -> queryUserByPhone(content)
            else -> listOf()
        }
        val result = users.map { user ->
            val id = user.getInt(UserM.ID)
            val state = user.getInt(UserM.STATE)
            val info = UserInfoM.findInfobyUserId(id)
            return@map User2Manage(
                    user = User.formModel(user),
                    info = UserInfo.fromModel(info),
                    state = explainState(state)
            )
        }
        if (controller.render == null){
            val message = Message(State.STATE_SUCCESS, data = result)
            controller.renderJson(message)
        }
    }

    private fun queryUserById(content: String): List<UserM>{
        val id = content.toIntOrNull()
        if (id == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_ILLEGAL_PARA))
            controller.renderJson(message)
            return listOf()
        }
        val user = UserM.AGENT.findById(id) ?: return listOf()
        return listOf(user)
    }

    private fun queryUserByUsername(content: String): List<UserM>{
        return UserM.findUserByUsername(content)
    }

    private fun queryUserByPhone(content: String): List<UserM>{
        return UserM.findUserByPhone(content)
    }

    private fun explainState(state: Int): Map<String, Boolean>{
        return hashMapOf(
                "login" to PermissionManager.checkPermission(state, Permission.LOGIN),
                "publish" to PermissionManager.checkPermission(state, Permission.PUBLISH),
                "buy" to PermissionManager.checkPermission(state, Permission.BUY),
                "comment" to PermissionManager.checkPermission(state, Permission.COMMENT)
        )
    }

    fun changeUserPermission(userId: Int, permission: String, value: Boolean){
        val user = UserM.AGENT.findById(userId)
        if (user == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_USER_USER_NOT_EXIST))
            controller.renderJson(message)
            return
        }
        var state = user.getInt(UserM.STATE)
        val which = when(permission){
            "login" -> Permission.LOGIN
            "publish" -> Permission.PUBLISH
            "buy" ->  Permission.BUY
            "comment" -> Permission.COMMENT
            else -> null
        }
        if (which == null){
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_ILLEGAL_PARA))
            controller.renderJson(message)
            return
        }
        state = if (value){
            PermissionManager.addUserPermission(state, which)
        }else{
            PermissionManager.removeUserPermission(state, which)
        }
        user[UserM.STATE] = state
        if (user.update()){
            val message = Message(State.STATE_SUCCESS, data = "")
            controller.renderJson(message)
        } else {
            val message = Message(State.STATE_FAIL, data = State.getEorrorStr(State.ERROR_SERVER_INSIDE_ERROR))
            controller.renderJson(message)
        }
    }
}